package com.smart.community.property.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.entity.property.UserPropertyCompany;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.commons.utils.StringUtils;
import com.smart.community.property.dto.AddEmployeeDTO;
import com.smart.community.property.dto.EmployeeQueryDTO;
import com.smart.community.property.dto.UpdateEmployeeDTO;
import com.smart.community.property.mapper.UserPropertyCompanyMapper;
import com.smart.community.property.service.IPropertyEmployeeService;
import com.smart.community.property.vo.EmployeeVO;
import com.smart.community.property.vo.UserVO;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 物业公司员工管理服务实现类
 * 
 * @author Wu.Liang
 * @since 2025-01-21
 */
@Slf4j
@Service
public class PropertyEmployeeServiceImpl extends ServiceImpl<UserPropertyCompanyMapper, UserPropertyCompany>
        implements IPropertyEmployeeService {

    @Override
    public PageResult<EmployeeVO> getPropertyCompanyEmployees(Long propertyCompanyId, EmployeeQueryDTO queryDTO) throws Exception {
        log.info("获取物业公司员工列表，物业公司ID：{}，查询参数：{}", propertyCompanyId, queryDTO);

        // 构建查询条件
        LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPropertyCompany::getPropertyCompanyId, propertyCompanyId);

        // 添加查询条件
        if (StringUtils.isNotBlank(queryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(UserPropertyCompany::getPosition, queryDTO.getKeyword())
                    .or()
                    .like(UserPropertyCompany::getDepartment, queryDTO.getKeyword())
                    .or()
                    .like(UserPropertyCompany::getEmployeeNo, queryDTO.getKeyword())
            );
        }

        if (StringUtils.isNotBlank(queryDTO.getPosition())) {
            queryWrapper.like(UserPropertyCompany::getPosition, queryDTO.getPosition());
        }

        if (StringUtils.isNotBlank(queryDTO.getDepartment())) {
            queryWrapper.like(UserPropertyCompany::getDepartment, queryDTO.getDepartment());
        }

        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(UserPropertyCompany::getStatus, queryDTO.getStatus());
        }

        if (queryDTO.getJoinDateStart() != null) {
            queryWrapper.ge(UserPropertyCompany::getJoinDate, queryDTO.getJoinDateStart());
        }

        if (queryDTO.getJoinDateEnd() != null) {
            queryWrapper.le(UserPropertyCompany::getJoinDate, queryDTO.getJoinDateEnd());
        }

        // 排序
        queryWrapper.orderByDesc(UserPropertyCompany::getCreateTime);

        // 分页查询
        Page<UserPropertyCompany> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<UserPropertyCompany> pageResult = this.page(page, queryWrapper);

        // 转换为VO
        List<EmployeeVO> employeeVOList = pageResult.getRecords().stream()
                .map(this::convertToEmployeeVO)
                .collect(Collectors.toList());

        return new PageResult<>(
                (int) pageResult.getCurrent(),
                (int) pageResult.getSize(),
                pageResult.getTotal(),
                employeeVOList
        );
    }

    @Override
    @GlobalTransactional
    public boolean addEmployeeToPropertyCompany(Long propertyCompanyId, AddEmployeeDTO addEmployeeDTO) throws Exception {
        log.info("添加员工到物业公司，物业公司ID：{}，员工信息：{}", propertyCompanyId, addEmployeeDTO);

        // 检查是否已关联
        LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPropertyCompany::getUserId, addEmployeeDTO.getUserId())
                .eq(UserPropertyCompany::getPropertyCompanyId, propertyCompanyId);

        if (this.count(queryWrapper) > 0) {
            throw new BusinessException("用户已关联该物业公司");
        }

        // 创建关联记录
        UserPropertyCompany userPropertyCompany = new UserPropertyCompany();
        userPropertyCompany.setUserId(addEmployeeDTO.getUserId());
        userPropertyCompany.setPropertyCompanyId(propertyCompanyId);
        userPropertyCompany.setPosition(addEmployeeDTO.getPosition());
        userPropertyCompany.setDepartment(addEmployeeDTO.getDepartment());
        userPropertyCompany.setEmployeeNo(addEmployeeDTO.getEmployeeNo());
        userPropertyCompany.setJoinDate(addEmployeeDTO.getJoinDate());
        userPropertyCompany.setStatus(1); // 在职
        userPropertyCompany.setRemark(addEmployeeDTO.getRemark());
        userPropertyCompany.setCreateBy(SecurityUtils.getCurrentUserId());
        userPropertyCompany.setCreateTime(LocalDateTime.now());
        userPropertyCompany.setUpdateBy(SecurityUtils.getCurrentUserId());
        userPropertyCompany.setUpdateTime(LocalDateTime.now());

        return this.save(userPropertyCompany);
    }

    @Override
    @GlobalTransactional
    public boolean updateEmployeeInfo(Long propertyCompanyId, Long employeeId, UpdateEmployeeDTO updateEmployeeDTO) throws Exception {
        log.info("更新员工信息，物业公司ID：{}，员工ID：{}，更新信息：{}", propertyCompanyId, employeeId, updateEmployeeDTO);

        // 检查关联记录是否存在
        UserPropertyCompany userPropertyCompany = this.getById(employeeId);
        if (userPropertyCompany == null) {
            throw new BusinessException("员工关联记录不存在");
        }

        if (!userPropertyCompany.getPropertyCompanyId().equals(propertyCompanyId)) {
            throw new BusinessException("员工不属于该物业公司");
        }

        // 更新信息
        if (StringUtils.isNotBlank(updateEmployeeDTO.getPosition())) {
            userPropertyCompany.setPosition(updateEmployeeDTO.getPosition());
        }
        if (StringUtils.isNotBlank(updateEmployeeDTO.getDepartment())) {
            userPropertyCompany.setDepartment(updateEmployeeDTO.getDepartment());
        }
        if (StringUtils.isNotBlank(updateEmployeeDTO.getEmployeeNo())) {
            userPropertyCompany.setEmployeeNo(updateEmployeeDTO.getEmployeeNo());
        }
        if (updateEmployeeDTO.getJoinDate() != null) {
            userPropertyCompany.setJoinDate(updateEmployeeDTO.getJoinDate());
        }
        if (updateEmployeeDTO.getStatus() != null) {
            userPropertyCompany.setStatus(updateEmployeeDTO.getStatus());
        }
        if (StringUtils.isNotBlank(updateEmployeeDTO.getRemark())) {
            userPropertyCompany.setRemark(updateEmployeeDTO.getRemark());
        }

        userPropertyCompany.setUpdateBy(SecurityUtils.getCurrentUserId());
        userPropertyCompany.setUpdateTime(LocalDateTime.now());

        return this.updateById(userPropertyCompany);
    }

    @Override
    @GlobalTransactional
    public boolean removeEmployeeFromPropertyCompany(Long propertyCompanyId, Long employeeId) throws Exception {
        log.info("移除员工，物业公司ID：{}，员工ID：{}", propertyCompanyId, employeeId);

        // 检查关联记录是否存在
        UserPropertyCompany userPropertyCompany = this.getById(employeeId);
        if (userPropertyCompany == null) {
            throw new BusinessException("员工关联记录不存在");
        }

        if (!userPropertyCompany.getPropertyCompanyId().equals(propertyCompanyId)) {
            throw new BusinessException("员工不属于该物业公司");
        }

        // 物理删除
        return this.removeById(employeeId);
    }

    @Override
    public List<UserVO> searchAvailableUsers(String keyword, Long excludePropertyCompanyId) throws Exception {
        log.info("搜索可分配的用户，关键词：{}，排除物业公司ID：{}", keyword, excludePropertyCompanyId);

        // 获取已关联的用户ID列表
        List<Long> associatedUserIds = new ArrayList<>();
        if (excludePropertyCompanyId != null) {
            LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPropertyCompany::getPropertyCompanyId, excludePropertyCompanyId);
            List<UserPropertyCompany> associatedUsers = this.list(queryWrapper);
            associatedUserIds = associatedUsers.stream()
                    .map(UserPropertyCompany::getUserId)
                    .collect(Collectors.toList());
        }

        // TODO: 通过Feign调用用户服务搜索用户
        // 暂时返回空列表，实际项目中应该调用用户服务
        List<UserVO> users = new ArrayList<>();
        
        return users;
    }

    @Override
    @GlobalTransactional
    public boolean batchAddEmployees(Long propertyCompanyId, List<AddEmployeeDTO> addEmployeeDTOList) throws Exception {
        log.info("批量添加员工，物业公司ID：{}，员工数量：{}", propertyCompanyId, addEmployeeDTOList.size());

        List<UserPropertyCompany> userPropertyCompanies = new ArrayList<>();

        for (AddEmployeeDTO addEmployeeDTO : addEmployeeDTOList) {
            // 检查是否已关联
            LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPropertyCompany::getUserId, addEmployeeDTO.getUserId())
                    .eq(UserPropertyCompany::getPropertyCompanyId, propertyCompanyId);

            if (this.count(queryWrapper) > 0) {
                throw new BusinessException("用户已关联该物业公司，用户ID：" + addEmployeeDTO.getUserId());
            }

            // 创建关联记录
            UserPropertyCompany userPropertyCompany = new UserPropertyCompany();
            userPropertyCompany.setUserId(addEmployeeDTO.getUserId());
            userPropertyCompany.setPropertyCompanyId(propertyCompanyId);
            userPropertyCompany.setPosition(addEmployeeDTO.getPosition());
            userPropertyCompany.setDepartment(addEmployeeDTO.getDepartment());
            userPropertyCompany.setEmployeeNo(addEmployeeDTO.getEmployeeNo());
            userPropertyCompany.setJoinDate(addEmployeeDTO.getJoinDate());
            userPropertyCompany.setStatus(1); // 在职
            userPropertyCompany.setRemark(addEmployeeDTO.getRemark());
            userPropertyCompany.setCreateBy(SecurityUtils.getCurrentUserId());
            userPropertyCompany.setCreateTime(LocalDateTime.now());
            userPropertyCompany.setUpdateBy(SecurityUtils.getCurrentUserId());
            userPropertyCompany.setUpdateTime(LocalDateTime.now());

            userPropertyCompanies.add(userPropertyCompany);
        }

        return this.saveBatch(userPropertyCompanies);
    }

    @Override
    public EmployeeVO getEmployeeDetail(Long propertyCompanyId, Long employeeId) throws Exception {
        log.info("获取员工详情，物业公司ID：{}，员工ID：{}", propertyCompanyId, employeeId);

        UserPropertyCompany userPropertyCompany = this.getById(employeeId);
        if (userPropertyCompany == null) {
            throw new BusinessException("员工关联记录不存在");
        }

        if (!userPropertyCompany.getPropertyCompanyId().equals(propertyCompanyId)) {
            throw new BusinessException("员工不属于该物业公司");
        }

        return convertToEmployeeVO(userPropertyCompany);
    }

    @Override
    public boolean isUserBelongToPropertyCompany(Long userId, Long propertyCompanyId) throws Exception {
        LambdaQueryWrapper<UserPropertyCompany> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPropertyCompany::getUserId, userId)
                .eq(UserPropertyCompany::getPropertyCompanyId, propertyCompanyId)
                .eq(UserPropertyCompany::getStatus, 1); // 在职状态

        return this.count(queryWrapper) > 0;
    }

    /**
     * 转换为EmployeeVO
     */
    private EmployeeVO convertToEmployeeVO(UserPropertyCompany userPropertyCompany) {
        EmployeeVO employeeVO = new EmployeeVO();
        BeanUtils.copyProperties(userPropertyCompany, employeeVO);

        // TODO: 通过Feign调用用户服务获取用户信息
        // 暂时设置默认值
        employeeVO.setUsername("用户" + userPropertyCompany.getUserId());
        employeeVO.setRealName("用户" + userPropertyCompany.getUserId());
        employeeVO.setPhone("");
        employeeVO.setEmail("");

        // 设置状态名称
        employeeVO.setStatusName(getStatusName(userPropertyCompany.getStatus()));

        return employeeVO;
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) return "";
        switch (status) {
            case 0: return "离职";
            case 1: return "在职";
            case 2: return "待入职";
            default: return "未知";
        }
    }
} 
